/**
 * @内容 牌九规则相关类及函数
 * @创建日期 2018-02-01
 */
#ifndef _PG_RULEMANAGER_H
#define _PG_RULEMANAGER_H

#include "Common.h"
#include "PGPubStruct.h"
// 牌九牌型
enum CardsType
{
	en_CardsType_None = 0,				  			// 无效牌型
	en_CardsType_BombOne = 1,			  			// 炸弹一
	en_CardsType_Devil = 2,				  			// 鬼子
	en_CardsType_Extreme = 3,			  			// 至尊宝
	en_CardsType_KingNine = 4,			  		// 天王九
	en_CardsType_DoubleDay = 5,			  		// 双天
	en_CardsType_EarthNineLady = 6,				// 地九靓靓
	en_CardsType_DoubleEarth = 7,		  		// 双地
	en_CardsType_DoubleMan = 8,			  		// 双人
	en_CardsType_TwoGoose = 9,			  		// 双鹅
	en_CardsType_DoublePlum = 10,		  		// 双梅
	en_CardsType_DoubleLongThree = 11,	  // 双长三
	en_CardsType_DoubleStool = 12,		  	// 两板凳
	en_CardsType_DoubleAxe = 13,		  		// 两斧头
	en_CardsType_RedHeadTen = 14,		  		// 红头十
	en_CardsType_DoubleHighSeven = 15, 	  // 双高七
	en_CardsType_Pratia = 16,			  			// 铜锤
	en_CardsType_MiscellaneousNine = 17,  // 杂九
	en_CardsType_MiscellaneousEight = 18, // 杂八
	en_CardsType_MiscellaneousSeven = 19, //杂七
	en_CardsType_MiscellaneousFive = 20,  // 杂五
	en_CardsType_DayBar = 21,			  			// 天杠
	en_CardsType_EarthBar = 22,			  		// 地杠
	en_CardsType_Day = 23,				  			//天
	en_CardsType_Earth = 24,			  			//地
	en_CardsType_Man = 25,				  			//人
	en_CardsType_Goose = 26,			  			//鹅
	en_CardsType_Long = 27,				  			//长
	en_CardsType_Short = 28,			  			//短
	en_CardCheck_Miscellaneous = 29				//杂
};
// 比较结果
enum CompareResult
{
	en_PGCompareResult_None = 0,					// 无效结果
	en_PGCompareResult_Greater = 1, 			// 大于
	en_PGCompareResult_Less = 2,					// 小于
	en_PGCompareResult_Draw = 3						//等于
};

//检测杠数
enum BarType
{
	en_BarType_None = 0,
	en_BarType_Head = 1,
	en_BarType_Second = 2,
	en_BarType_Third = 3
 
};
//比较选择
enum ComOpt
{
	en_ComOpt_All = 0,
	en_ComOpt_First = 1,
	en_ComOpt_Second = 2
};

class Rule;
struct Cards;
class RuleManager : public Singleton<RuleManager>
{
public:
	RuleManager();
	~RuleManager();
	// 注册规则
	void RegisterRule(CardsType type, Rule *pRule);
	void OtherSingleRegisterRule(Rule *pRule);
	// 检测牌型
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	// 比较牌大小
	CompareResult Compare(const Cards &self, const Cards &other, const uint8 &opt = 0);
	//比较最终结果
	CompareResult CalculationResults(const uint32 &fresult, const uint32 &sresult);
	//检测每组牌的杠数
	BarType CheckBarType(const uint32 &bartype, const uint32 &barpoint);
	//确定最终杠数
	BarType CompareBarType(const BarType firBarType, const BarType secBarType);

		private :
		// 规则集合
		std::map<CardsType, Rule *> m_mapRules;
};

#define   sRuleMgr   RuleManager::getSingleton()

///////////////////////////////////////////////////////////////////////////////////
/**
 * @内容 牌九规则的检测及牌型比较
 * @功能说明 以下规则的比较功能是以庄家为自身，闲家为目标
 */

/*虚基类也叫抽象类，不能直接生成对象，只能被继承，并且在纯虚函数被重写，抽象类作为派生类的公共的根
；虚函数和纯虚函数都是为了多态性服务，使得基类指针或引用可以指向变化多端的子类以实现变化多端的版本。
但虚函数意味着子类可以不必必须拥有自己的个性化版本，而是可以使用基类提供的备用版本。纯虚函数意味着
子类必须拥有自己的个性化版本，但同时仍然保留可以使用基类的备用版本的权利 
实现了纯虚函数的子类，该纯虚函数在子类中就编程了虚函数，子类的子类即孙子类可以覆盖该虚函数，由多态
方式调用的时候动态绑定*/
class Rule
{
public:
	Rule(){}
	virtual ~Rule(){}
	virtual CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety) = 0;
	virtual CompareResult Compare(const uint32 &stype, const uint32 &otype, 
	const uint32 &spoint, const uint32 &opoint) = 0;

	CompareResult CompareCardValue(const uint32 sCard, const uint32 oCards);
	CompareResult CompareCardtype(const uint32 sType, const uint32 oType);
};
// 炸弹一
class BombOneRule : public Rule
{
public:
  BombOneRule() {}
  ~BombOneRule() {}
  CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
  CompareResult Compare(const uint32 &stype, const uint32 &otype,const uint32 &spoint, const uint32 &opoint);
};
// 鬼子
class DevilRule : public Rule
{
  public:
	DevilRule() {}
	~DevilRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 至尊宝
class ExtremeRule : public Rule
{
  public:
	ExtremeRule() {}
	~ExtremeRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 天王九
class KingNineRule : public Rule
{
  public:
	KingNineRule() {}
	~KingNineRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双天
class doubleDayRule : public Rule
{
  public:
	doubleDayRule() {}
	~doubleDayRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 地九娘娘
class EarthNineLadyRule : public Rule
{
  public:
	EarthNineLadyRule() {}
	~EarthNineLadyRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双地
class DoubleEarthRule : public Rule
{
  public:
	DoubleEarthRule() {}
	~DoubleEarthRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双人
class DoubleManRule : public Rule
{
  public:
	DoubleManRule() {}
	~DoubleManRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双鹅
class TwoGooseRule : public Rule
{
  public:
	TwoGooseRule() {}
	~TwoGooseRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双梅
class DoublePlumRule : public Rule
{
  public:
	DoublePlumRule() {}
	~DoublePlumRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双长三
class DoubleLongthreeRule : public Rule
{
  public:
	DoubleLongthreeRule() {}
	~DoubleLongthreeRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 两板凳
class DoubleStoolRule : public Rule
{
  public:
	DoubleStoolRule() {}
	~DoubleStoolRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 两斧头
class DoubleAxeRule : public Rule
{
  public:
	DoubleAxeRule() {}
	~DoubleAxeRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 红头十
class RedHreadRule : public Rule
{
  public:
	RedHreadRule() {}
	~RedHreadRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 双高七
class DoubleHightSevenRule : public Rule
{
  public:
	DoubleHightSevenRule() {}
	~DoubleHightSevenRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 铜锤
class PratiaRule : public Rule
{
  public:
	PratiaRule() {}
	~PratiaRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 杂九
class MiscellaneousNineRule : public Rule
{
  public:
	MiscellaneousNineRule() {}
	~MiscellaneousNineRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 杂八
class MiscellaneousEightRule : public Rule
{
  public:
	MiscellaneousEightRule() {}
	~MiscellaneousEightRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 杂七
class MiscellaneousSevenRule : public Rule
{
  public:
	MiscellaneousSevenRule() {}
	~MiscellaneousSevenRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 杂五
class MiscellaneousFiveRule : public Rule
{
  public:
	MiscellaneousFiveRule() {}
	~MiscellaneousFiveRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 天杠
class DayBarRule : public Rule
{
  public:
	DayBarRule() {}
	~DayBarRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 地杠
class EarthBarRule : public Rule
{
  public:
	EarthBarRule() {}
	~EarthBarRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};
// 非对牌
class OtherSingleRule : public Rule
{
  public:
	OtherSingleRule() {}
	~OtherSingleRule() {}
	CardsType Check(std::vector<PaiGowType> &vecCards,SpecialType &spety);
	CompareResult Compare(const uint32 &stype, const uint32 &otype, const uint32 &spoint, const uint32 &opoint);
};

#endif